#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<syslog.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<signal.h>

#define LOCKFILE "/var/run/daemon.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
sigset_t mask;

void reread(void)
{

}

void *thr_fn(void *arg)
{
	int err,signo;
	for(;;)
	{
		err = sigwait(&mask,&signo);
		if(err !=0 )
			syslog(LOG_ERR,"sigwait error");
			exit(1);
		switch(signo)
		{
			case SIGHUP:
			     syslog(LOG_INFO,"Re_reading configuaration file");
				 reread();
				 break;

			case SIGTERM:
			     syslog(LOG_INFO,"got SIGTERM;exiting");
				 exit(0);

			default:
			     syslog(LOG_INFO,"unexpted signal %d\n",signo);
		}
	}
	return 0;
}

int already_running(void)
{
	int   fd;
	char  buf[16];

	fd = open(LOCKFILE,O_RDWR|O_CREAT,LOCKMODE);
	if(fd <0 )
	{
		syslog(LOG_ERR,"can't open %s:%s",LOCKFILE,strerror(errno));
		exit(1);
    }
	if(lockfile(fd) < 0)
	{
		if(errno == EACCES || errno == EAGAIN)
		{
			close(fd);
			return(1);
		}
		syslog(LOG_ERR,"can't lock %s:%s\n",LOCKFILE,strerror(errno));
		exit(1);
	}

	ftruncate(fd,0);
	sprintf(buf,"%ld",(long)getpid());
	write(fd,buf,strlen(buf)+1);
	return 0;
}
int main(int argc,char **argv)
{
	int              err;
	pthread_t        tid;
	char             *cmd;
	struct sigaction sa;

	if((cmd = strrchr(argv[0],'/'))==NULL)
		cmd = argv[0];
	else
		cmd++;
	
	daemonize(cmd);

	if(already_running())
	{
		syslog(LOG_ERR,"daemon already running");
		exit(1);
	}

	sa.sa_handler = SIG_DFL;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if(sigaction(SIGHUP,&sa,NULL) < 0)
		printf("can't restore SIGHUP default\n");
	sigfillset(&mask);
	if((err = pthread_sigmask(SIG_BLOCK,&mask,NULL)) != 0)
		printf("SIG_BLOCK error\n");

	err = pthread_create(&tid,NULL,thr_fn,0);
	if(err != 0)
		printf("can't create thread\n");

	exit(0);

}
